package pages;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import database.DBException;
import database.DBUtils;

import templates.Template;

/**
 * Servlet implementation class InstrumentInfo
 */
public class InstrumentInfo extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private static final String pageTitle = "Instrument Info";
	private static final String templateName = "instrument_info";
	private static final String timeSlotTemplateName = "time_slot_combo";

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public InstrumentInfo() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String instrumentID = "";

		try {
			instrumentID = LMUtils.getRequestParameterValueNotEmpty(request,
					"instrumentID");
			Template template = getInstrumentInfoTemplate(instrumentID);
			template.addChange("error", LMUtils.getRequestAttribute(request,
					"error"));
			// template = LMUtils.adminMenu(template);
			response.getWriter().print(
					template.createPage(pageTitle, LMUtils
							.getUserLogin(request)));
		} catch (Exception e) {
			try {
				response.getWriter().print(
						ErrorPage.generateErrorPage(e.getMessage(), LMUtils
								.getUserLogin(request)));
			} catch (InternalErrorException e1) {
				response.getWriter().print(e1.getMessage());
			}
		}

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String instrumentID = "";
		String error = "";
		try {
			instrumentID = LMUtils.getRequestParameterValueNotEmpty(request,
					"instrumentID");
		} catch (MissingParameterException e) {
			doGet(request, response);
			return;
		}

		try {
			LMUtils.getRequestParameterValueNotEmpty(request, "updateInfo");
			try {
				String newName = LMUtils.getRequestParameterValueNotEmpty(
						request, "instrumentName");
				String newDescription = LMUtils.getRequestParameterValue(
						request, "description");
				updateInfo(instrumentID, "Name", newName);
				updateInfo(instrumentID, "description", newDescription);
			} catch (MissingParameterException e) {
				error = "Please specify instrument name";
			} catch (Exception e) {
				error = e.getMessage();
			}

		} catch (MissingParameterException e) {
			// no info update
		}

		try {
			LMUtils.getRequestParameterValueNotEmpty(request, "changeTimeSlot");
			try {
				String newTimeSlot = LMUtils.getRequestParameterValue(request,
						"timeSlot");
				updateInfo(instrumentID, "timeSlot", newTimeSlot);
			} catch (Exception e) {
				error = e.getMessage();
			}

		} catch (MissingParameterException e) {
			// no changeTimeSlot
		}

		try {
			LMUtils.getRequestParameterValueNotEmpty(request, "enableDisable");
			try {
				String messageForUsers = LMUtils.getRequestParameterValue(
						request, "messageForUsers");
				updateInfo(instrumentID, "messageForUsers", messageForUsers);
				enableDisable(instrumentID);
			} catch (Exception e) {
				error = e.getMessage();
			}

		} catch (MissingParameterException e) {
			// no enableDisable
		}
		LMUtils.setRequestAttribute(request, "error", error);
		doGet(request, response);
	}

	/**
	 * Generates InstrumentInfo Template
	 * 
	 * @param instrumentID
	 * @return
	 * @throws DBException
	 * @throws InternalErrorException
	 * @throws UserErrorException
	 */
	private Template getInstrumentInfoTemplate(String instrumentID)
			throws DBException, InternalErrorException, UserErrorException {
		Connection conn = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			String instrumentsTableName = LMUtils.getContextParameterValue(
					getServletContext(), "db.InstrumentsTableName");
			String typesTableName = LMUtils.getContextParameterValue(
					getServletContext(), "db.TypesTableName");
			String query = "SELECT A.`id`, B.`name`, A.`Name` as `instrumentName`,  A.`timeSlot`, A.`description`, A.`messageForUsers`, A.`isActive`"
					+ " FROM `"
					+ instrumentsTableName
					+ "` as A, `"
					+ typesTableName
					+ "` as B "
					+ " WHERE A.`typeID` = B.`id` AND A.`id` = ? LIMIT 1;";
			conn = DBUtils.getConnection();
			stmt = conn.prepareStatement(query);
			stmt.setString(1, instrumentID);
			rs = stmt.executeQuery();
			if (!rs.next()) {
				throw new UserErrorException("Instrument not found");
			}
			Template template = new Template(templateName);
			template.addChange("instrumentType", rs.getString("name"));
			template
					.addChange("instrumentName", rs.getString("instrumentName"));
			template.addChange("instrumentID", rs.getString("id"));
			template.addChange("timeSlot", rs.getString("timeSlot"));
			template.addChange("description", rs.getString("description"));
			template.addChange("messageForUsers", rs
					.getString("messageForUsers"));

			if (rs.getBoolean("isActive")) {
				template.addChange("activeClass", "active");
				template.addChange("active_string", "Active");
			} else {
				template.addChange("activeClass", "blocked");
				template.addChange("active_string", "Disabled");
			}

			// timeSlot combo
			Template timeSlotTemplate = new Template(timeSlotTemplateName);
			template.addChange("timeslots_combo", timeSlotTemplate
					.applyChanges());

			return template;
		} catch (SQLException e) {
			throw new DBException("Can't get instrument info: "
					+ e.getMessage(), e);
		} finally {
			DBUtils.close(rs);
			DBUtils.close(stmt);
			DBUtils.close(conn);
		}
	}

	/**
	 * Updates instrument info
	 * 
	 * @param instrumentID
	 * @param fieldName
	 * @param fieldValue
	 * @throws DBException
	 * @throws InternalErrorException
	 */
	private void updateInfo(String instrumentID, String fieldName,
			String fieldValue) throws DBException, InternalErrorException {
		Connection conn = null;
		PreparedStatement stmt = null;
		try {
			String instrumentsTableName = LMUtils.getContextParameterValue(
					getServletContext(), "db.InstrumentsTableName");
			String query = "UPDATE `" + instrumentsTableName + "` SET `"
					+ fieldName + "` = ? WHERE `id` = ? LIMIT 1;";
			conn = DBUtils.getConnection();
			stmt = conn.prepareStatement(query);
			stmt.setString(1, fieldValue);
			stmt.setString(2, instrumentID);
			stmt.execute();

		} catch (SQLException e) {
			throw new DBException("Can't update instrument info: "
					+ e.getMessage(), e);
		} finally {
			DBUtils.close(stmt);
			DBUtils.close(conn);
		}
	}

	/**
	 * Changes the status of instrument
	 * 
	 * @param instrumentID
	 * @throws InternalErrorException
	 * @throws DBException
	 */
	private void enableDisable(String instrumentID)
			throws InternalErrorException, DBException {
		Connection conn = null;
		PreparedStatement stmt = null;
		try {
			// updating isEnable field
			String instrumentsTableName = LMUtils.getContextParameterValue(
					getServletContext(), "db.InstrumentsTableName");
			String query = "UPDATE `" + instrumentsTableName
					+ "` SET `isActive` = 1 - `isActive` WHERE `id` = ?";
			conn = DBUtils.getConnection();
			stmt = conn.prepareStatement(query);
			stmt.setString(1, instrumentID);
			stmt.execute();
		} catch (SQLException e) {
			throw new DBException("Can't update instrument status: "
					+ e.getMessage(), e);
		} finally {
			DBUtils.close(stmt);
			DBUtils.close(conn);
		}

	}
}
